#ifndef WBDED_INC
#include "wbded.h"
#endif

#include "calc.h"

static ULONG STDMETHODCALLTYPE
ids_addref(WB_IDropSource *This)
{
	// increment object reference count
    return InterlockedIncrement(&This->m_lRefCount);
}

static ULONG STDMETHODCALLTYPE
ids_release (WB_IDropSource *This)
{
	LONG count = InterlockedDecrement(&This->m_lRefCount);

	if(count == 0) g_free(This);

	return count;
}

static HRESULT STDMETHODCALLTYPE
ids_queryinterface(	WB_IDropSource *This, 
					REFIID riid, 
					LPVOID *ppvObject)
{
	if (IsEqualGUID (riid, &IID_IUnknown) || IsEqualGUID (riid, &IID_IDropSource))
    {
        ids_addref (This);
        *ppvObject = This;
        return S_OK;
    }
 	else
    {
        *ppvObject = 0;
        return E_NOINTERFACE;
    }
}

static HRESULT STDMETHODCALLTYPE
ids_querycontinuedrag(	WB_IDropSource* This, 
						BOOL fEscapePressed, 
						DWORD grfKeyState )
{
	// if the <Escape> key has been pressed since the last call, cancel the drop
	if (fEscapePressed == TRUE) {
		
		SendMessage(calcs[gslot].hwndLCD, WM_LBUTTONUP, 0, 0);
		return DRAGDROP_S_CANCEL;
	}
		
	// if the <LeftMouse> button has been released, then do the drop!
	if((grfKeyState & MK_LBUTTON) == 0) return DRAGDROP_S_DROP;
		
	// continue with the drag-drop
	return S_OK;
}

static HRESULT STDMETHODCALLTYPE
ids_givefeedback(	WB_IDropSource* This, 
					DWORD dwEffect ) 
{
	/*
	FORMATETC format = {0};
	format.cfFormat = RegisterClipboardFormat("DragWindow");
	format.dwAspect = DVASPECT_CONTENT;
	format.lindex = -1;
	format.tymed = TYMED_HGLOBAL;
	STGMEDIUM stg = {0};
	if(SUCCEEDED(This->pDataObject->lpVtbl->GetData(This->pDataObject, &format, &stg))) {
		if(stg.hGlobal) {
			#define WM_INVALIDATEDRAGIMAGE WM_USER + 3   // WM_USER + 2 works, too; WM_USER + 1 hides the drag image

			HWND hWndDragWindow = *((HWND*) GlobalLock(stg.hGlobal));
			GlobalUnlock(stg.hGlobal);

			SendMessage(hWndDragWindow, WM_INVALIDATEDRAGIMAGE, 0, 0);
		}
		ReleaseStgMedium(&stg);
		SetCursor((HCURSOR) LoadImage(NULL, MAKEINTRESOURCE(OCR_NORMAL), IMAGE_CURSOR, 0, 0, LR_DEFAULTCOLOR | LR_DEFAULTSIZE | LR_SHARED));
		return S_OK;
	} else {
		return DRAGDROP_S_USEDEFAULTCURSORS;
	}*/
	
	return DRAGDROP_S_USEDEFAULTCURSORS;
}

static WB_IDropSourceVtbl ids_vtbl = {
	ids_queryinterface,
	ids_addref,
	ids_release,
	ids_querycontinuedrag,
	ids_givefeedback
};



WB_IDropSource * WB_IDropSource_new (void) {
	WB_IDropSource *result = g_new0(WB_IDropSource, 1);

	if (result == NULL) return NULL;
	
	result->ids.lpVtbl = (IDropSourceVtbl*) &ids_vtbl;
	result->m_lRefCount = 1;

	return result;
}


HRESULT CreateDropSource(WB_IDropSource **ppDropSource)
{
	if(ppDropSource == NULL) return E_INVALIDARG;

	*ppDropSource = WB_IDropSource_new();

	return (*ppDropSource) ? S_OK : E_OUTOFMEMORY;
}
